﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;

namespace VideoRentalShop.View.Templates
{
    public delegate void FinishedCallback();


    /// <summary>
    /// Logika interakcji dla klasy StepPanel.xaml
    /// </summary>
    public partial class StepPanel : UserControl, IHidible
    {
        public FinishedCallback Finished;
        private static readonly GridLength MIN_GRID_LENGTH = new GridLength(0d, GridUnitType.Star);
        private static readonly GridLength MAX_GRID_LENGTH = new GridLength(1d, GridUnitType.Star);
        private static readonly Duration PROGRESS_ANIMATION_DURATION = new Duration(TimeSpan.FromSeconds(0.5d));
        private List<StepPanelContent> _panels;
        private List<string> _titles;
        private int _currentIdx = -1;
        private int _completedStage = 0;
        private bool _completed;


        public StepPanel() : this(null) { }

        public StepPanel(string title)
        {
            InitializeComponent();
            btnBack.Content = VideoRentalShop.Properties.Resources.StrBtnBack;
            btnBack.Visibility = Visibility.Collapsed;
            btnNext.Content = VideoRentalShop.Properties.Resources.StrBtnNext;
            btnNext.Visibility = Visibility.Collapsed;

            if (string.IsNullOrWhiteSpace(title))
            {
                lblTitle.Content = VideoRentalShop.Properties.Resources.StrProcessTitle;
            }
            else
            {
                lblTitle.Content = title.Trim();
            }

            IsVisibleChanged += new DependencyPropertyChangedEventHandler(VisibilityChanged);

            _panels = new List<StepPanelContent>();
            _titles = new List<string>();
        }


        public void AddPanel(StepPanelContent panel, string title)
        {
            _panels.Add(panel);
            _titles.Add(title);
            btnNext.Content = VideoRentalShop.Properties.Resources.StrBtnNext;
            btnNext.Visibility = Visibility.Visible;

            panel.Visibility = Visibility.Collapsed;
            panel.Width = gridContent.Width;
            panel.Height = gridContent.Height;
            gridContent.Children.Add(panel);

            if (_currentIdx == -1)
            {
                ShowPanel();
            }

            UpdateProgressInfo();
        }

        public void InsertPanel(int idx, StepPanelContent panel, string title)
        {
            if (idx >= 0) 
            {
                if (idx < _panels.Count)
                {
                    _panels.Insert(idx, panel);
                    _titles.Insert(idx, title);
                }
                else
                {
                    AddPanel(panel, title);
                }
            }
            else
            {
                _panels.Insert(0, panel);
                _titles.Insert(0, title);
            }

            UpdateProgressInfo();
        }

        public void SetTitle(string title)
        {
            if (!string.IsNullOrWhiteSpace(title))
            {
                lblTitle.Content = title;
            }
        }

        public bool CanHide
        {
            get
            {
                if (_completedStage > 0 && !_completed)
                {
                    var result = MessageBox.Show("Opuszczenie tego procesu spowoduje utratę dotychczas wprowadzonych danych. Czy chcesz kontynuować?", "Ostrzeżenie", MessageBoxButton.YesNo, MessageBoxImage.Warning);

                    if (result != MessageBoxResult.Yes)
                    {
                        return false;
                    }
                }

                return true;
            }
        }


        private void btnBack_Click(object sender, RoutedEventArgs e)
        {
            ShowPanel(_currentIdx - 1);
        }

        private void btnNext_Click(object sender, RoutedEventArgs e)
        {
            if (_currentIdx >= 0 && _currentIdx < _panels.Count)
            {
                if (!_panels[_currentIdx].ValidateForm())
                {
                    return;
                }
                _panels[_currentIdx].UpdateItem();
            }

            if (_currentIdx == _panels.Count - 1)
            {
                ProcessFinished();
            }
            else
            {
                ShowPanel(_currentIdx + 1);
            }
        }


        private void VisibilityChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (Visibility == Visibility.Visible)
            {
                Reset();
            }
        }

        private void ShowPanel(int idx = 0)
        {
            var oldPanel = _currentIdx;
            UpdateCurrentIndex(idx);
            
            if (oldPanel != idx)
            {
                UpdateButtons();
                ChangePanel(oldPanel);
                UpdateProgressInfo();
            }
        }

        private void UpdateCurrentIndex(int idx)
        {
            if (_panels.Count > 0)
            {
                if (idx <= 0)
                {
                    _currentIdx = 0;
                }
                else if (idx >= _panels.Count) 
                {
                    _currentIdx = _panels.Count - 1;
                }
                else
                {
                    _currentIdx = idx;
                }
            }
            else
            {
                _currentIdx = -1;
            }
        }

        private void UpdateButtons()
        {
            if (_currentIdx > 0)
            {
                btnBack.Visibility = Visibility.Visible;
            }
            else
            {
                btnBack.Visibility = Visibility.Collapsed;
            }

            if (_currentIdx < _panels.Count - 1)
            {
                btnNext.Content = VideoRentalShop.Properties.Resources.StrBtnNext;
            }
            else
            {
                btnNext.Content = VideoRentalShop.Properties.Resources.StrBtnFinish;
            }
        }

        private void ChangePanel(int oldIdx)
        {
            var correctOld = oldIdx >= 0 && oldIdx < _panels.Count;
            if (correctOld)
            {
                _panels[oldIdx].Visibility = Visibility.Collapsed;
            }

            if (_currentIdx >= 0 && _currentIdx < _panels.Count)
            {
                if (correctOld)
                {
                    var item = _panels[oldIdx].Item;
                    if (item != null)
                    {
                        _panels[_currentIdx].Item = item;
                    }
                }
                _panels[_currentIdx].Visibility = Visibility.Visible;
                if (_currentIdx > _completedStage)
                {
                    _completedStage = _currentIdx;
                }
            }
        }

        private void UpdateProgressInfo()
        {
            var step = _currentIdx + 1;
            var title = string.Empty;

            if (_currentIdx >= 0 && _currentIdx < _panels.Count)
            {
                if (!string.IsNullOrWhiteSpace(_titles[_currentIdx]))
                {
                    title = ": " + _titles[_currentIdx];
                }
            }

            lblInfo.Content = string.Format(VideoRentalShop.Properties.Resources.StrStepPanelInfo, step, _panels.Count, title);

            var colAnimation1 = CreateGridLengthAnimation(colProgress1.Width, step);
            var colAnimation2 = CreateGridLengthAnimation(colProgress2.Width, _panels.Count - step);

            colProgress1.BeginAnimation(ColumnDefinition.WidthProperty, colAnimation1);
            colProgress2.BeginAnimation(ColumnDefinition.WidthProperty, colAnimation2);
        }

        private GridLengthAnimation CreateGridLengthAnimation(GridLength from, double to, double? seconds = null)
        {
            var animation = new GridLengthAnimation();
            animation.From = from;
            animation.To = new GridLength(to, GridUnitType.Star);
            if (seconds.HasValue)
            {
                animation.Duration = new Duration(TimeSpan.FromSeconds(seconds.Value));
            }
            else
            {
                animation.Duration = PROGRESS_ANIMATION_DURATION;
            }

            return animation;
        }

        public void Reset()
        {
            _completedStage = 0;
            _completed = false;
            foreach (var panel in _panels)
            {
                panel.ClearForm();
            }

            colProgress1.Width = MIN_GRID_LENGTH;
            colProgress2.Width = MAX_GRID_LENGTH;

            ShowPanel();
        }

        private void ProcessFinished()
        {
            _completed = true;
            if (Finished != null)
            {
                Finished();
            }

            Reset();
        }
    }
}
